from PySide6.QtCore import Qt, QRectF
from PySide6.QtGui import QBrush, QColor, QPen, QFont, QPainter, QPainterPath
from PySide6.QtWidgets import QGraphicsItem, QGraphicsTextItem, QGraphicsDropShadowEffect

from 节点插槽 import NodePort


class QDMGraphicsNode(QGraphicsItem):
    def __init__(
            self,
            scene,
            node_id,
            custom_info,
            remarks,
            node_position=None,
            parent=None
    ) -> None:
        super().__init__(parent)

        self.node_id = node_id
        self.custom_info = custom_info
        self.remarks = remarks
        self.scene = scene  # 获取场景
        # 设置节点可移动、可选择、可发送几何变化
        self.setFlag(
            QGraphicsItem.GraphicsItemFlag.ItemIsMovable |
            QGraphicsItem.GraphicsItemFlag.ItemIsSelectable |
            QGraphicsItem.GraphicsItemFlag.ItemSendsGeometryChanges
        )

        self.width = 180  # 设置节点的宽度和高度
        self.height = 300  # 设置节点的宽度和高度
        self.radius = 10  # 设置节点的圆角半径
        self.title_height = 25  # 设置标题的高度
        self.remarks_height = 30  # 设置备注的高度
        self.title_padding = 8  # 设置标题的内边距
        self.outline_pen_width = 3  # 设置轮廓线的粗细

        self._brush_title_color = QBrush(QColor('#B22222'))  # 设置标题背景色为红色
        self._brush_background_color = QBrush(QColor(50, 50, 50, 180))  # 设置内容背景色为透明黑色
        self._brush_remarks_color = QBrush(QColor('#1E90FF'))  # 设置备注背景色为深蓝色

        self._pen_default = QPen(QColor('#B22222'), self.outline_pen_width)  # 设置默认轮廓线颜色为红色
        self._pen_selected = QPen(QColor('#ffff00'), self.outline_pen_width)  # 设置选中轮廓线颜色为黄色

        # 选中投影
        self._shadow = QGraphicsDropShadowEffect()
        self._shadow.setOffset(0, 0)
        self._shadow.setBlurRadius(20)
        self._shadow_color = QColor('#aaeeee00')

        # 初始化标题、内容和备注文本
        self.title_item = None
        self.custom_info_item = None
        self.remarks_item = None
        self.init_title_text_remakes()

        # 移动标志
        self.moved_flag = False
        self.start_pos = None
        self.line_item = None

        # 添加插槽
        self.port_padding = 5  # 设置插槽的内边距
        self.in_port = None
        self.out_port = None
        self.error_port = None
        self._node_position = node_position
        self._edges = []  # 用于存储连接的边
        self._connected_nodes = []  # 用于存储连接的节点

    def init_title_text_remakes(self):
        # 初始化标题
        self.title_item = QGraphicsTextItem(self)
        title_font = QFont('consolas')
        title_font.setBold(True)  # 设置字体加粗
        self.title_item.setDefaultTextColor(QColor(Qt.GlobalColor.white))
        self.title_item.setFont(title_font)
        self.title_item.setPos(self.title_padding, 0)
        self.title_item.setTextWidth(self.width - 2 * self.title_padding)
        self.title_item.setPlainText("Node Title")
        # 初始化 custom_info
        self.custom_info_item = QGraphicsTextItem(self)
        self.custom_info_item.setDefaultTextColor(QColor(Qt.GlobalColor.white))
        self.custom_info_item.setFont(QFont('consolas'))
        self.custom_info_item.setPos(self.title_padding, self.title_height + 10)
        self.custom_info_item.setTextWidth(self.width - 2 * self.title_padding)
        self.custom_info_item.setPlainText(self.custom_info)
        # 初始化 remarks
        self.remarks_item = QGraphicsTextItem(self)
        self.remarks_item.setDefaultTextColor(QColor(Qt.GlobalColor.white))
        self.remarks_item.setFont(QFont('consolas'))
        self.remarks_item.setPos(self.title_padding, self.height - self.remarks_height)
        self.remarks_item.setTextWidth(self.width - 2 * self.title_padding)
        self.remarks_item.setPlainText(self.remarks)
        # 设置不同的文本颜色
        self.title_item.setDefaultTextColor(QColor('#FFFFFF'))  # 标题文字颜色
        self.custom_info_item.setDefaultTextColor(QColor('#FFFF00'))  # 内容文字颜色
        self.remarks_item.setDefaultTextColor(QColor('#FFFFFF'))  # 备注文字颜色

    def boundingRect(self) -> QRectF:
        return QRectF(0, 0, self.width, self.height).normalized()

    def paint(self, painter: QPainter, option, widget=None) -> None:
        """绘制节点显示器"""
        # 设置阴影颜色为透明
        self._shadow.setColor('#00000000')
        self.setGraphicsEffect(self._shadow)
        # 如果节点被选中，设置阴影颜色为预定义的颜色
        if self.isSelected():
            self._shadow.setColor(self._shadow_color)
            self.setGraphicsEffect(self._shadow)

        # 画背景颜色
        node_outline = QPainterPath()
        node_outline.addRoundedRect(0, 0, self.width, self.height, self.radius, self.radius)
        painter.setPen(Qt.PenStyle.NoPen)
        painter.setBrush(self._brush_background_color)
        painter.drawPath(node_outline.simplified())

        # 画title的背景颜色
        title_outline = QPainterPath()
        title_outline.setFillRule(Qt.FillRule.WindingFill)
        title_outline.addRoundedRect(0, 0, self.width, self.title_height, self.radius, self.radius)
        # 添加左上角和右上角的矩形，以确保标题背景的圆角效果
        title_outline.addRect(0, self.title_height - self.radius, self.radius, self.radius)
        title_outline.addRect(self.width - self.radius, self.title_height - self.radius, self.radius, self.radius)
        painter.setPen(Qt.PenStyle.NoPen)
        painter.setBrush(self._brush_title_color)
        painter.drawPath(title_outline.simplified())

        # 画备注的背景颜色
        remarks_outline = QPainterPath()
        remarks_outline.setFillRule(Qt.FillRule.WindingFill)
        remarks_outline.addRoundedRect(
            0, self.height - self.remarks_height, self.width, self.remarks_height,
            self.radius, self.radius
        )
        # 添加左下角和右下角的矩形，以确保备注背景的圆角效果
        remarks_outline.addRect(0, self.height - self.remarks_height, self.radius, self.radius)
        remarks_outline.addRect(self.width - self.radius, self.height - self.remarks_height, self.radius, self.radius)
        painter.setPen(Qt.PenStyle.NoPen)
        painter.setBrush(self._brush_remarks_color)
        painter.drawPath(remarks_outline.simplified())

        # 根据节点是否被选中，设置不同的画笔颜色
        if not self.isSelected():
            painter.setPen(self._pen_default)
            painter.setBrush(Qt.BrushStyle.NoBrush)
            painter.drawPath(node_outline)
        else:
            painter.setPen(self._pen_selected)
            painter.setBrush(Qt.BrushStyle.NoBrush)
            painter.drawPath(node_outline)

    def add_port(self, port: NodePort, position: str = '左下'):
        """添加一个插槽"""
        port.add_to_parent_node(self, self.scene)
        # 位置放置在节点的底部
        if position == '左下':
            port.setPos(self.port_padding * 2, self.remarks_item.y() - port.boundingRect().height() - self.port_padding)
            self.in_port = port  # 设置输入插槽
        elif position == '右下':
            port.setPos(self.width - port.boundingRect().width() - self.port_padding * 2,
                        self.remarks_item.y() - port.boundingRect().height() - self.port_padding
                        )
            self.out_port = port  # 设置输出插槽
        elif position == '右中':
            port.setPos(
                self.width - port.boundingRect().width() - self.port_padding * 2,
                self.remarks_item.y() - self.port_padding * 2 - port.boundingRect().height() * 2
            )
            self.error_port = port  # 设置错误插槽

    def add_connected_node(self, node, edge):
        self._connected_nodes.append(node)  # 添加到连接的节点列表
        self._edges.append(edge)

    def itemChange(self, change, value):
        if change == QGraphicsItem.GraphicsItemChange.ItemPositionChange:
            if len(self._edges) > 0:
                for edge in self._edges:
                    edge.update()
        return super().itemChange(change, value)
